package parteSintatica;

import java.util.LinkedList;

public class Gramatica {
	
	private LinkedList<Terminal> terminais;
	
	public Gramatica(){
		terminais = new LinkedList<Terminal>();
		
		montarGramatica();
	}

	//TOKEN:				`token`
	//TERMINAL:				<terminal>
	//EXPRESS�O REGULAR:	[simbolo que exite ou nao](express�o){repeti��o de express�o}
	private void montarGramatica() {
		Terminal programa = new Terminal("programa");
		programa.addInstrucao("<instrucao>");
		terminais.add(programa);
		
		Terminal instrucao = new Terminal("instrucao");
		instrucao.addInstrucao("<Funcao ES>");
		instrucao.addInstrucao("<declara��o>");
		terminais.add(instrucao);
		
		Terminal declaracao = new Terminal("declaracao");
		declaracao.addInstrucao("<declaracao de variavel>");
		declaracao.addInstrucao("<declaracao de funcao>");
		terminais.add(declaracao);
		
		Terminal declaracaoVar = new Terminal("declaracao de variavel");
		declaracaoVar.addInstrucao("`let` <id> `:` <tipo> `=` <expr>");
		terminais.add(declaracaoVar);
		
		Terminal declaracaoFun = new Terminal("declaracao de funcao");
		declaracaoFun.addInstrucao("`let` <id> `:` <tipo>{<tipo>} `->` <tipo> `=` `fun` <id>{<id>} `->` <expr>");
		terminais.add(declaracaoFun);
		
		Terminal id = new Terminal("id");
		id.addInstrucao("(a..z|A..Z){a..z|A..Z|0..9}");
		terminais.add(id);
		
		Terminal tipo = new Terminal("tipo");
		tipo.addInstrucao("<tipo simples>");
		tipo.addInstrucao("<tipo array>");
		tipo.addInstrucao("<tipo tupla>");
		terminais.add(tipo);
		
		Terminal tipo_simples = new Terminal("tipo simples");
		tipo_simples.addInstrucao("<id>");
		terminais.add(tipo_simples);
		
		Terminal tipo_array = new Terminal("tipo array");
		tipo_array.addInstrucao("<tipo simples> `array` {`array`}");
		terminais.add(tipo_array);
		
		Terminal tipo_tupla = new Terminal("tipo tupla");
		tipo_tupla.addInstrucao("(<tipo simples>|<tipo array>) `*` <tipo>");
		terminais.add(tipo_tupla);
		
		Terminal expr = new Terminal("expr");
		expr.addInstrucao("<expr simples>");
		expr.addInstrucao("<expr tupla>");
		expr.addInstrucao("<expr array>");
		terminais.add(expr);
		
		Terminal expr_simples = new Terminal("expr simples");
		expr.addInstrucao("<expr int>");
		expr.addInstrucao("<expr float>");
		expr.addInstrucao("<expr char>");
		expr.addInstrucao("<expr string>");
		expr.addInstrucao("<expr bool>");
		terminais.add(expr_simples);
		
		Terminal expr_tupla = new Terminal("expr tupla");
		expr_tupla.addInstrucao("`(`<expr simples>`,`<expr>`)`");
		terminais.add(expr_tupla);
		
		Terminal expr_array = new Terminal("expr array");
		expr_array.addInstrucao("<array simples>");
		expr_array.addInstrucao("<array de array>");
		terminais.add(expr_array);
		
		Terminal array_simples = new Terminal("array simples");
		array_simples.addInstrucao("<array int>");
		array_simples.addInstrucao("<array float>");
		array_simples.addInstrucao("<array bool>");
		array_simples.addInstrucao("<array char>");
		array_simples.addInstrucao("<array string>");
		terminais.add(array_simples);
		
		Terminal array_int = new Terminal("array int");
		array_int.addInstrucao("`{`<expr int> {`,`<expr int>}`}`");
		terminais.add(array_int);
		
		Terminal array_float = new Terminal("array float");
		array_float.addInstrucao("`{`<expr float> {`,`<expr float>}`}`");
		terminais.add(array_float);
		
		Terminal array_bool = new Terminal("array bool");
		array_bool.addInstrucao("`{`<expr bool> {`,`<expr bool>}`}`");
		terminais.add(array_bool);
		
		Terminal array_char = new Terminal("array char");
		array_char.addInstrucao("`{`<expr char> {`,`<expr char>}`}`");
		terminais.add(array_char);
		
		Terminal array_string = new Terminal("array string");
		array_string.addInstrucao("`{`<expr string> {`,`<expr string>}`}`");
		terminais.add(array_string);
		
		Terminal array_de_array = new Terminal("array de array");
		array_de_array.addInstrucao("`{`<expr array {`,`<expr array>}`}`");
		terminais.add(array_de_array);
		
		Terminal expr_int = new Terminal("expr int");
		expr_int.addInstrucao("<valor int>");
		expr_int.addInstrucao("<termo int>");
		expr_int.addInstrucao("(<expr int>|<termo int>) (`+`|`-`) (<valor int>|<termo int>)");
		terminais.add(expr_int);
		
		Terminal termo_int = new Terminal("termo int");
		termo_int.addInstrucao("(<termo  int>|<value int>) (`*`|`/`) <valor int>");
		terminais.add(termo_int);
		
		Terminal valor_int = new Terminal("valor int");
		valor_int.addInstrucao("[`-`](0..9){0..9}{0..9}");
		terminais.add(valor_int);
		
		Terminal expr_float = new Terminal("expr_float");
		expr_float.addInstrucao("<valor float>");
		expr_float.addInstrucao("<termo float>");
		expr_float.addInstrucao(" (<expr float>|<termo float>) (`+.`|`-.`) (<valor float>|<termo float>)");
		terminais.add(expr_float);
		
		Terminal termo_float = new Terminal("termo float");
		termo_float.addInstrucao("(<termo  float>|<value float>) (`*.`|`/.`) <valor float>");
		terminais.add(termo_float);
		
		Terminal valor_float = new Terminal("valor float");
		valor_float.addInstrucao("[`-`](0..9){0..9}`.`{0..9}");
		terminais.add(valor_float);
		
		Terminal expr_char = new Terminal("expr char");
		expr_char.addInstrucao("<valor char>");
		terminais.add(expr_char);
		
		Terminal valor_char = new Terminal("valor char");
		valor_char.addInstrucao("`'`(a..z|A..Z|0..9)`'`");
		terminais.add(valor_char);
		
		Terminal expr_string = new Terminal("expr string");
		expr_string.addInstrucao("<valor string>");
		expr_string.addInstrucao("<valor string> `^` <expr string>");
		terminais.add(expr_string);
		
		Terminal valor_string = new Terminal("valor string");
		valor_string.addInstrucao("`\"`(a..z|A..|0..9|`_`){(a..z|A..|0..9|`_`)}`\"`");
		terminais.add(valor_string);
		
		Terminal expr_bool = new Terminal("expr bool");
		expr_bool.addInstrucao("<valor bool>");
		expr_bool.addInstrucao("<compara��o>");
		expr_bool.addInstrucao("(<valor bool>|<compara��o>) <op bool> <expr bool>");
		terminais.add(expr_bool);
		
		Terminal op_bool = new Terminal("op bool");
		op_bool.addInstrucao("`&`");
		op_bool.addInstrucao("`|`");
		op_bool.addInstrucao("`!`");
		terminais.add(op_bool);
		
		Terminal comparacao = new Terminal("comparacao");
		comparacao.addInstrucao("<compara��o int>");
		comparacao.addInstrucao("<compara��o float>");
		comparacao.addInstrucao("<compara��o char>");
		comparacao.addInstrucao("<compara��o string>");
		comparacao.addInstrucao("<compara��o bool>");
		terminais.add(comparacao);
		
		Terminal comparacao_int = new Terminal("comparacao int");
		comparacao_int.addInstrucao("<expr int> (`<`|`<=`|`>`|`>=`|`=`|`<>`) <expr int>");
		terminais.add(comparacao_int);
		
		Terminal comparacao_float = new Terminal("comparacao float");
		comparacao_float.addInstrucao("<expr float> (`<`|`<=`|`>`|`>=`|`=`|`<>`) <expr float>");
		terminais.add(comparacao_float);
		
		Terminal comparacao_char = new Terminal("comparacao char");
		comparacao_char.addInstrucao("<expr char> (`=`|`<>`) <expr char>");
		terminais.add(comparacao_char);
		
		Terminal comparacao_string = new Terminal("comparacao string");
		comparacao_string.addInstrucao("<expr string> (`=`|`<>`) <expr string>");
		terminais.add(comparacao_string);
		
		Terminal valor_bool = new Terminal("valor bool");
		valor_bool.addInstrucao("`true`");
		valor_bool.addInstrucao("`false`");
		terminais.add(valor_bool);	
	}
	
	public LinkedList<Terminal> getTerminais(){
		return terminais;
	}
	
	
}
